﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Infrastructure.Data;
using Keepo.Models;
using AlbumDesigner.Models.ViewModels;
using Keepo.Helpers;
using Keepo.Models.ViewModels;
using AlbumDesigner.Models.Types;
using AlbumDesigner.Models.Enums;
using AlbumDesigner.Helpers;
using Keepo.Models.Services;

namespace AlbumDesigner.Controllers
{
    public class UsersController : Controller
    {
        [CheckPermission(section = "Users")]
        public ActionResult Index()
        {
            using (var repository = new GenericRepository())
            {
                var viewModel = new UsersListViewModel();

                //get all permissions (for DDL use)
                var userPermissions = repository.Find<UserPermission>(m => m.UserPermissionId != (int)AlbumUsers.Client).ToList();
                viewModel.Permissions = new SelectList(userPermissions, "UserPermissionId", "UserPermissionName");

                return View(viewModel);
            }
        }

        [CheckPermission(section = "Users")]
        [HttpPost]
        public ActionResult UsersList(int? UserPermissionId)
        {
            using (var repository = new GenericRepository())
            {
                //get all regular users (not the ones that have been created for album use only)
                var usersList = repository.Find<User>(m => m.UserPermissionId != (int)AlbumUsers.Client);

                //if filter by user permissions
                if (UserPermissionId != null)
                {
                    usersList = usersList.Where(m => m.UserPermissionId == UserPermissionId.Value);
                }

                var users = (from u in usersList
                             select new UserRegistrationData(u)).ToList();

                return Json(users);
            }
        }

        public ActionResult Add()
        {
            using (var repository = new GenericRepository())
            {
                //get all permissions (for DDL use)
                var userPermissions = repository.Find<UserPermission>(m => m.UserPermissionId != (int)AlbumUsers.Client).ToList();
                ViewBag.Permissions = new SelectList(userPermissions, "UserPermissionId", "UserPermissionName");
            }

            ViewBag.Password = Guid.NewGuid().ToString().Substring(0, 5);

            return PartialView();
        }

        [HttpPost]
        public ActionResult Add(User user)
        {
            if (!ModelState.IsValid)
            {
                return Json(new { Key = false, Value = "הנתונים אינם תקינים." });
            }

            using (var repository = new GenericRepository())
            {
                user.Activate = true;
                user.RegistrationDate = DateTime.Now;

                //insert this user to DB
                repository.Add<User>(user);
                repository.UnitOfWork.SaveChanges();
            }

            return Json(new { Key = true, Value = "המשתמש נוסף בהצלחה." });
        }

        public ActionResult Logout()
        {
            UserHelper.Logout(Request, Response, Session);

            return RedirectToAction("Index", "Home");
        }

        public ActionResult EditorLogin(int id) // "id" parameter is the Order Number
        {
            using (var repository = new GenericRepository())
            {
                //get the album title
                var album = repository.Find<Album>(m => m.OrderNum == id).FirstOrDefault();
                if (album.IsRemoved)
                {
                    return RedirectToAction("Index", "Home");
                }

                var systemSettings = repository.GetAll<SystemSetting>().FirstOrDefault();
                if (systemSettings.IsOffline)
                {
                    ViewBag.MessageText = systemSettings.OfflineMessage;
                    return View("SystemOffline");
                }

                ViewBag.AlbumId = album.AlbumId;
                ViewBag.AlbumTitle = album.Title;

                //get list of all AlbumSections of this Album
                var albumSections = repository.Find<AlbumSection>(m => m.AlbumId == album.AlbumId);
                ViewBag.SectionsList = new SelectList(albumSections, "AlbumSectionId", "Title");

                return View();
            }
        }

        [HttpPost]
        public ActionResult EditorLogin(EditorLoginData loginData)
        {
            User editorFound = null;
            object redirectRouteValues = null;

            using (var repository = new GenericRepository())
            {
                //login as editor of AlbumSection
                if (loginData.AlbumSectionId != null)
                {
                    var albumSection = repository.GetByKey<AlbumSection>(loginData.AlbumSectionId);
                    if (albumSection.Editor != null)
                    {
                        if (albumSection.Editor.Password == loginData.Password)
                        {
                            editorFound = albumSection.Editor;
                        }
                    }
                    redirectRouteValues = new { controller = "Albums", action = "AlbumSectionEditorView", id = albumSection.AlbumSectionId, album = albumSection.Album.OrderNum };
                }
                //login as editor of Album
                else if (loginData.AlbumId != null)
                {
                    var album = repository.GetByKey<Album>(loginData.AlbumId);
                    if (album.Editor != null)
                    {
                        if (album.Editor.Password == loginData.Password)
                        {
                            editorFound = album.Editor;
                        }
                    }
                    redirectRouteValues = new { controller = "Albums", action = "AlbumEditorView", id = album.OrderNum };
                }

                //if editor found
                if (editorFound != null)
                {
                    //login this user using the login data - get Key/Value result
                    var loginResult = UserHelper.Login(editorFound, true, Response, Session);

                    return Json(new { Key = true, Value = Url.RouteUrl(redirectRouteValues) });
                }

                return Json(new { Key = false, Value = "" });
            }
        }

        public ActionResult UpdateUser(User user)
        {
            using (var repository = new GenericRepository())
            {
                //find the specified user by id
                var existingUser = repository.GetByKey<User>(user.UserId);

                //if exist
                if (existingUser != null)
                {
                    //edit the user's properties
                    existingUser.Username = user.Username;
                    existingUser.Password = user.Password;
                    existingUser.FirstName = user.FirstName;
                    existingUser.LastName = user.LastName;
                    existingUser.Email = user.Email;
                    existingUser.Phone = user.Phone;
                    existingUser.UserPermissionId = user.UserPermissionId;
                }
                repository.UnitOfWork.SaveChanges();

                return Json(user.UserId);
            }
        }

        public ActionResult DeleteUser(int id)
        {
            using (var repository = new GenericRepository())
            {
                //find the specified user by id
                var existingUser = repository.GetByKey<User>(id);

                //if there is album for this user - set him as Null
                var album = repository.First<Album>(m => m.EditorId == id);
                if (album != null)
                {
                    repository.First<Album>(m => m.EditorId == id).EditorId = null;
                }

                //delete the item
                repository.Delete<User>(existingUser);
                repository.UnitOfWork.SaveChanges();
            }

            return Json(true);
        }


        public ActionResult CanUserEdit(int albumId = -1, int sectionId = -1, int pageId = -1)
        {
            return Json(AlbumsLogic.canUserEdit(albumId, sectionId, pageId));
        }

        [HttpPost]
        public ActionResult IsUserSleeping()
        {
            if (UserHelper.IsLogon())
            {
                using (var db = new AlbumContext())
                {
                    var userId = UserHelper.CurrentUser().UserId;

                    var userLastLogin = (from u in db.Users
                                         where u.UserId == userId
                                         select u.LastLogin).FirstOrDefault();

                    //get the time since this user has been active
                    var timeSinceLastLogin = DateTime.Now - userLastLogin.Value;
                    var minutesSinceLastLogin = Convert.ToInt32(timeSinceLastLogin.TotalMinutes);

                    var minutesTillDissconnection = 60 - minutesSinceLastLogin;

                    //if more than X minutes since last action
                    if (minutesSinceLastLogin > 30)
                    {
                        return Json(new { Key = true, Value = minutesTillDissconnection });
                    }
                    else
                    {
                        return Json(new { Key = false, Value = minutesTillDissconnection });
                    }
                }
            }

            return Json(null);
        }

        public ActionResult KeepAlive()
        {
            return Json(true);
        }

        public ActionResult ActiveUsers()
        {
            using (var db = new AlbumContext())
            {
                var users = db.Users.Where(m => m.LastLogin != null).ToList();
                var usersOnline = users.Where(m => m.LastLogin.Value > DateTime.Now.AddMinutes(-5));
                var usernames = usersOnline.Select(u => u.Username).ToList();
                
                return Json(usernames, JsonRequestBehavior.AllowGet);
            }
        }

        // Check what is the type of this user as editor (דפוס/מרכזת/תלמיד)
        public ActionResult GetEditorRole()
        {
            var user = UserHelper.CurrentUser();

            //if login
            if (user != null)
            {
                // Default is NONE
                EditorRoleEnum editorType = EditorRoleEnum.None;

                if (user.UserPermissionId == (int)AlbumUsers.Admin)
                {
                    editorType = EditorRoleEnum.Admin;
                }
                else
                {
                    using (var db = new AlbumContext())
                    {
                        //if the user is Editor of AlbumSection
                        var albumSection = db.AlbumSections.FirstOrDefault(m => m.EditorId == user.UserId);
                        if (albumSection != null)
                        {
                            editorType = EditorRoleEnum.AlbumSectionEditor;
                        }

                        //if the user is Editor of Album
                        var album = db.Albums.FirstOrDefault(m => m.EditorId == user.UserId);
                        if (album != null)
                        {
                            editorType = EditorRoleEnum.AlbumEditor;
                        }
                    }
                }

                return Json(editorType, JsonRequestBehavior.AllowGet);
            }
            //not login
            else
            {
                return new HttpUnauthorizedResult();
            }
        }
    }
}